using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using FeedAntGame.Control;
using FeedAntGame.Sprite;
using FeedAntGame.Sprite.Event;


namespace FeedAntGame.Component.Dialog
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class PickCandyDlg : Microsoft.Xna.Framework.DrawableGameComponent
    {

        SpriteBatch spriteBatch;
        Texture2D bg;
        Vector2 bgPos;

        List<BaseSprite> spriteList = new List<BaseSprite>();
        //Animation field
        Vector2 direction = Vector2.Zero;
        bool goBack = false;

        //Array candyFeed
        Vector2[,] candyPos = new Vector2[4,5];
        bool[,] blankCell = new bool[4, 5]; // -1 : blank. 
        Point[] choosenPos = new Point[4];
        Candy.TYPE[] choosenStatus = new Candy.TYPE[4]; // -1 : blank.

        //Level
        int level = 1;


        //Button
        Button goButton;
        Vector2 goPos;

        /************************************************************************/
        /*                      Get/Set                                                                     */
        /************************************************************************/

        public int Level
        {
            get { return level; }
            set { level = value; }
        }
        /************************************************************************/
        /*                      Constructor                                                                     */
        /************************************************************************/
        public PickCandyDlg(Game game, int level=1)
            : base(game)
        {
            // TODO: Construct any child components here
            this.level = level;
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: AddOneCandyFeed your initialization code here

            
            reset();

            // Initialize candies topLeftPos and status (blank)
            for (int i = 0; i < candyPos.GetLength(0); i++)
            {
                for (int j = 0; j < candyPos.GetLength(1); j++)
                {
                    candyPos[i, j] = new Vector2(30 + i * 103f  , 122 + j * 94 +3);
                    blankCell[i, j] = true;
                }
            }
            
            for (int i = 0; i < choosenStatus.GetLength(0); i++)
            {
                choosenPos[i] = new Point(30 + i * 103, 20);
                choosenStatus[i] = Candy.TYPE.NONE;
            }

            //Initialize go button topLeftPos
            goPos = new Vector2(445, 505);

            base.Initialize();
        }

        protected override void LoadContent()
        {
            // TODO: AddOneCandyFeed your load content code here
            spriteBatch = new SpriteBatch(Game.GraphicsDevice);
            bg = Game.Content.Load<Texture2D>(@"Images\pick_candy_background");
            bgPos = new Vector2(0, 0);
            //
            // Button go
            //
            goButton = new Button(Game, Button.TYPE.GO, goPos);
            EventSprite goSprite = (EventSprite)goButton.Sprite;
            goSprite.Enable = false;
            goSprite.Hover += new EventSprite.HoverButton(this.onHandyShow);
            goSprite.Click += new EventSprite.ClickButton(this.onGoClick);
            base.LoadContent();
        }
        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            // TODO: AddOneCandyFeed your update code here

            //Animation
            if (direction.X < 0 && !goBack)
            {
                direction.X = 1;
            }

            if (goBack)
            {
                direction.X = -1;
                if (direction.X <= -1 * (Game.Window.ClientBounds.Width / 2))
                {
                    this.Enabled = false;
                    this.Visible = false;
                }
            }

            //Check if game is ready 
            if (this.ready())
            {
                (goButton.Sprite as EventSprite).Enable = true;
            }
            else
            {
                (goButton.Sprite as EventSprite).Enable = false;
            }
            //Update for all sprite in sprite list
            for (int i = 0; i < spriteList.Count; i++)
            {
                BaseSprite s = spriteList.ElementAt<BaseSprite>(i);
                if (direction.X < 0)
                {
                    //CandyFeedSprite
                    if (s is CandyPickerSprite)
                    {
                        s.Position = (s as CandyPickerSprite).BackPos ;
                    }
                    //Button
                    else if (s is EventSprite)
                    {
                        s.Position = new Vector2(goPos.X, goPos.Y) ;
                        
                    }
                }
                if ((goButton.Sprite as EventSprite).IsPlaySoundHover())
                {
                    ((GameFA)Game).PlayCue(goButton.Sprite.collisionCueName);
                }
                s.Update(gameTime, Game.Window.ClientBounds);
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            // TODO: AddOneCandyFeed your draw code here

            spriteBatch.Begin();

            // Draw bg 
            spriteBatch.Draw(bg, new Rectangle((int)bgPos.X, (int)bgPos.Y, bg.Width,bg.Height),
                Color.White);
            
            // Draw sprite list
            foreach (BaseSprite s in spriteList)
                s.Draw(gameTime, spriteBatch);

            spriteBatch.End();
            base.Draw(gameTime);
        }

        /************************************************************************/
        /*                              Event                                                                     */
        /************************************************************************/

        private void onHandyShow()
        {
            ((GameFA)Game).Cursor.State = Cursor.STATE_TYPE.HAND;
        }
        private void onGoClick()
        {
            //Transfer pick result to PlayManager
            ((GameFA)Game).playManager.CandyFeedTypes = this.choosenStatus;

            //Enable PlayManager
            ((GameFA)Game).playManager.Enabled = true;

            //Close pick candyFeed
            ((GameFA)Game).ClosePickCandy();            

        }
        private void onClickCandy(EventSprite candy)
        {
            Point pos = new Point(Mouse.GetState().X, Mouse.GetState().Y);
            if (pos.Y >= candyPos[0, 0].Y)
            {

                // pick candyFeed
                for (int k = 0; k < choosenStatus.GetLength(0); k++)
                {
                    if (choosenStatus[k] == Candy.TYPE.NONE)
                    {
                        candy.Position = new Vector2(choosenPos[k].X, choosenPos[k].Y);
                        choosenStatus[k] = (candy as CandyPickerSprite).Type;
                        return;
                    }
                }
            }
            else
            {
                // unPick candyFeed
                Point mouse = new Point(Mouse.GetState().X, Mouse.GetState().Y);
                int temp = 3;
                for (int k = 0; k < 4; k++)
                {
                    if (mouse.X > choosenPos[k].X)
                    {
                        temp = k;
                    }
                }
                choosenStatus[temp] = Candy.TYPE.NONE;
                candy.Position = (candy as CandyPickerSprite).BackPos;
            }
        }


        /************************************************************************/
        /*                      Other methods                                                                     */
        /************************************************************************/
        //-------------------------------------------------------------------------------
        public void Start(int lv)
        {
            reset();
            this.level = lv;
            AddCandy();
            this.Enabled = true;
            this.Visible = true;
        }

        public void Finish(PlayManager playManager)
        {
            goBack = true;
            this.Enabled = false;
            this.Visible = false;
        }
        //-----------------------------------------------------------------------------------
        private void reset()
        {
            direction.X = -1*(Game.Window.ClientBounds.Width / 2+100);
            goBack = false;
            for (int i = 0; i < choosenStatus.GetLength(0); i++)
            {
                choosenStatus[i] = Candy.TYPE.NONE;
            }
            for (int i = 0; i < candyPos.GetLength(0); i++)
            {
                for (int j = 0; j < candyPos.GetLength(1); j++)
                {
                    blankCell[i, j] = true;
                }
            }
            spriteList.Clear();
        }

        /// <summary>
        /// Check ready condition for "Go" button.
        /// </summary>
        /// <returns></returns>
        private bool ready()
        {
            bool ret = true;
            for (int i = 0; i < choosenStatus.GetLength(0); i++)
            {
                if (choosenStatus[i] == Candy.TYPE.NONE)
                {
                    ret = false;
                    return ret;
                }
            }
            return ret;
        }
        //-------------------------------------------------------------------------------------
        public void AddCandy()
        {
            reset();
            spriteList.Add(goButton.Sprite);
            switch (level)
            {
                case 1:
                    addCandyLv1();
                    break;
                case 2:
                    addCandyLv2();
                    break;
            }
            
        }

        private void addCandyLv1()
        {
            AddOneCandy(0, 0, Candy.TYPE.ORANGE);
            AddOneCandy(1, 0, Candy.TYPE.ORANGE);
            AddOneCandy(2, 0, Candy.TYPE.ORANGE);
            AddOneCandy(3, 0, Candy.TYPE.PEARL);
        }

        private void addCandyLv2()
        {
            AddOneCandy(0, 0, Candy.TYPE.ORANGE);
            AddOneCandy(1, 0, Candy.TYPE.PEARL);
            AddOneCandy(2, 0, Candy.TYPE.PEARL);
            AddOneCandy(3, 0, Candy.TYPE.PEARL);
        }
        /// <summary>
        /// AddOneCandyFeed candyFeed to candyFeed grid
        /// </summary>
        /// <param name="i"></param>
        /// <param name="j"></param>
        private void AddOneCandy(int i, int j, Candy.TYPE type)
        {
            CandyPicker candyPicker = new CandyPicker(Game, type, candyPos[i, j]);
            CandyPickerSprite candy = (CandyPickerSprite)candyPicker.Sprite;
            spriteList.Add(candy);
            candy.Hover += new EventSprite.HoverButton(this.onHandyShow);
            candy.Click += new EventSprite.ClickButton(
                () =>
                {
                    onClickCandy(candy);
                });
        }
        //-------------------------------------------------------------------------------------------------
        
      


    }
}
